package ltd.sshine.networkserver.factory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import lombok.extern.slf4j.Slf4j;
import ltd.sshine.networkserver.handler.HttpProxyChannelHandler;
import ltd.sshine.networkserver.holder.ProxyServerHolder;

import java.net.BindException;
import java.net.InetSocketAddress;

@Slf4j
public class ProxyServerFactory {

    public static HttpProxyChannelHandler create(int localPort) throws  BindException {
        log.debug("开启端口" + localPort);
        HttpProxyChannelHandler httpProxyChannelHandler = new HttpProxyChannelHandler();
        ServerBootstrap serverBootstrap = new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nssc) throws Exception {
                        nssc.pipeline().addLast(new HttpServerCodec());
                        nssc.pipeline().addLast(new HttpObjectAggregator(1024 * 1024 * 1024));
                        nssc.pipeline().addLast(httpProxyChannelHandler);
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        ChannelFuture future = serverBootstrap.bind(new InetSocketAddress(localPort));
        ProxyServerHolder.addChannel(httpProxyChannelHandler,future.channel());
        try {
            future.sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


        return httpProxyChannelHandler;

    }
}
